#include "SGKAgent.h"
#include "matrix4.h"
#include "GOD.h"

extern HDC hDC;
extern int nFontList;

CBrain::CBrain()
	{
		m_pOwner = 0;
		m_pCurrentAction = 0;

		Action a;
		a.name = "ShootAtPlayer";
		a.animationTime = 0.2f;
		a.post.push_back(Condition(PLAYERHURT, true));
		a.post.push_back(Condition(HASAMMO, false));
		a.pre.push_back(Condition(GUNLOADED, true));
		a.pre.push_back(Condition(GUNAIMED, true));
		availableActions.push_back(a);

		Action b;
		b.name = "PickUpAmmo";
		b.animationTime = 0.5f;
		b.post.push_back(Condition(HASAMMO, true));
		b.pre.push_back(Condition(ISATAMMO, true));
		availableActions.push_back(b);

		Action c;
		c.name = "goto";
		c.animationTime = 1.1f; // SPECIAL
		// special post condition for goto handled by code.
		availableActions.push_back(c);

		Action d;
		d.name = "LoadGun";
		d.animationTime = 0.45f; // ha ha
		d.pre.push_back(Condition(HASAMMO, true));
		d.pre.push_back(Condition(GUNLOADED, false));
		d.post.push_back(Condition(GUNLOADED, true));
		availableActions.push_back(d);

		Action e;
		e.name = "AimAtTarget";
		e.animationTime = 1.5f;
		e.pre.push_back(Condition(HASTARGET, true));
		e.post.push_back(Condition(GUNAIMED, true));
		availableActions.push_back(e);

	}

void CBrain::Serve(SGKAgent * owner){m_pOwner = owner;}


bool CBrain::formulatePlan(Condition * goal, bool val)
	{
		m_plan.push(availableActions[2]);
		m_pOwner->SetDestination(vec3f(((float)((rand() % 4000) - 2000) / 100.0f), 0.f,((float)((rand() % 4000) - 2000) / 100.0f)));
		return true;
	}

void CBrain::update(float dt)
	{
		if (m_plan.size() == 0)
		{
			formulatePlan(God::GetInstance()->Conditions(PLAYERHURT), true); // todo: create a master list of actions with enumerateable indices for easy access YAY! [DONE]  later: load these from file.  even later: make a tool.
			//m_pCurrentAction = &availableActions[2]; // goto	
		} else {
			if (m_pCurrentAction)
			{
				m_pCurrentAction->animationTime -= dt;
				if (m_pCurrentAction->animationTime < 0.0f)
				{
					m_plan.pop();
					m_pCurrentAction = 0;
				}
			}
			else
			{
				m_pCurrentAction = &m_plan.front();
			}
		}

	}

SGKAgent::SGKAgent(void)
{
	m_Matrix.make_identity();
	m_Dest.x = 0.0;
	m_Dest.y = 0.0;
	m_Dest.z = 0.0;
}

//SGKAgent::~SGKAgent(void)
//{
//}

void SGKAgent::Init(void)
{
	quad = gluNewQuadric();
	gluQuadricNormals(quad, true);
	m_Brain.Serve(this);
}

void SGKAgent::Kill(void)
{
	gluDeleteQuadric(quad);
}
	
void SGKAgent::DrawText(char * text, vec3f pos)
{
	glColor3f(1.0f, 1.0f, 1.0f);
	glRasterPos3f(pos.x, pos.y, pos.z);
	glListBase(nFontList);
	glCallLists((GLsizei)strlen(text), GL_UNSIGNED_BYTE, text);
}


void SGKAgent::Draw(void)
{
	glPushMatrix();
		glColor3f(0.1f, 1.f, 0.1f);

		glMultMatrixd(m_Matrix.ma);

		gluSphere(quad, m_fRadius, 50, 50);
		gluCylinder(quad, (double)m_fRadius * 1.1, 0.0, (double)m_fRadius * 3.14, 24, 24);

		//Draw Current Action Name
		DrawText(m_Brain.currentBehavior(), vec3f(0.f, 0.2f, 0.f));

	glPopMatrix();

}

void SGKAgent::Update(float dt)
{
    if (m_Brain.currentBehavior() == "goto")
	{
		m_Matrix.zx = (m_Dest.x - m_Matrix.wx);
		m_Matrix.zy = (m_Dest.y - m_Matrix.wy);
		m_Matrix.zz = (m_Dest.z - m_Matrix.wz);

		double len = sqrt((m_Matrix.zx * m_Matrix.zx) + (m_Matrix.zy * m_Matrix.zy) + (m_Matrix.zz * m_Matrix.zz));
		m_Matrix.zx /= len;
		m_Matrix.zy /= len;
		m_Matrix.zz /= len;

		m_Matrix.wx += m_Matrix.zx * dt;
		m_Matrix.wy += m_Matrix.zy * dt;
		m_Matrix.wz += m_Matrix.zz * dt;

		//if (vec3d(m_Dest - vec3d(m_Matrix.wx, m_Matrix.wy, m_Matrix.wz)).magnitude() < 0.01)
		//{
		//	//is at destination = true;
		//	God::GetInstance()->Conditions(conditionID::
		//}

	}
	m_Brain.update(dt);
	
	
}
